#include <stdbool.h>
#include "page.h"

// 校验手机号码是否有效
// 返回值：成功 true， 失败 false
bool isValidPhone(long phone) 
{
     // 手机号码是11位数字，以1开头
    if (phone < 10000000000LL || phone > 19999999999LL)
    {
        return false;
    }
    // 第二位数字是3-9之间的数字
    long secondDigit = (phone / 100000000LL) % 10;
    return secondDigit >= 3 && secondDigit <= 9;
}

// 校验密码是否有效
// 返回值：成功 true， 失败 false
bool isValidPassword(const char *password)
{
    if (password == NULL) return false;
    int length = 0;
    for (int i = 0; password[i] != '\0'; ++i) 
    {
        if (!(('0' <= password[i] && password[i] <= '9') 
        || ('a' <= password[i] && password[i] <= 'z')
        || ('A' <= password[i] && password[i] <= 'Z'))) 
            return false; // 检查是否为字母或数字
        ++length;
    }
    //正则表达式(调用库) 用户名不能有 ;:\/...
    return length <= 22; // 检查密码长度是否不超过22位
}

// 校验年龄是否有效
// 返回值：成功 true， 失败 false
bool isValidAge(int age)
{
    if(age <= 0 || age > 200)
        return false;
    return true;
}

// 校验姓名是否有效
// 返回值：成功 true， 失败 false
bool isValidName(const char* name)
{
    return strlen(name) < 24;
}
/*
    参数：
        pUser 用户信息空间地址
    功能：登录
    返回值：
        0  登录成功
        -1 程序异常
        1  用户不存在
        2  重复登录
        3  密码不正确
*/
int loginPage(PUserType pUser)
{
    int res = -1;
    bool isValid = 0;
    long phone = 0;
    char password[PASSWORD_SIZE];

    while(1)
    {
        // 1）电话号、密码输入
        ClearScreen();
        ChangeCenter(2);
        PrintCenter("电话号:");
        scanf("%ld", &pUser->userId);
        PrintCenter("密码:");
        scanf("%s", pUser->password);

        isValid = isValidPhone(pUser->userId) && isValidPassword(pUser->password);
        
        if(!isValid)
        {    
            // 提示输入参数错误
            PrintWran("输入手机号/密码不正确！\n");
            // 校验失败则重新输入
            continue;
        }
        else
        {
            break;
        }
    }
    
    // 3）进行登录
    res = RequestLogin(pUser);
    if(res == 2)
    {
        PrintWran("已有账号登录！\n");
    }
    else if(res == 3)
    {
        PrintWran("密码不正确！\n");
    }
    else if(res == 1)
    {
        PrintWran("账号未注册！\n");
    }
    return res;
}

/*
    参数：
        pUser 用户信息空间地址
    功能：注册
    返回值：
        0  注册成功
        -1 程序异常
        1  用户存在 
        2  注册失败
*/
int registerPage(PUserType pUser)
{
    int res = -1;
    bool isValid = false;
    long phone = 0;//电话号
    char userName[USERNAME_SIZE] = "";//用户名
    char password[PASSWORD_SIZE] = "";//密码

    while(1)
    {
        // 1）电话号、用户名、密码输入
        ClearScreen();
        ChangeCenter(3);
        PrintCenter("电话号:");
        scanf("%ld", &pUser->userId);

        //用户名输入
        memset(pUser->userName, 0, sizeof(pUser->userName));
        PrintCenter("用户名:");
        scanf("%s", pUser->userName);

        //密码输入
        memset(pUser->password, 0, sizeof(pUser->password));
        PrintCenter("密码:");
        scanf("%s", pUser->password);

        isValid = isValidPhone(pUser->userId) && isValidPassword(pUser->password);
        
        if(!isValid)
        {    
            // 提示输入参数错误
            PrintWran("手机号/密码不正确！\n");
            // 校验失败则重新输入
            continue;
        }
        else
        {
            pUser->state = 0;
            break;
        }
    }

    res = RequestRegister(pUser);//进行注册
    if(res == 2)
    {
        PrintWran("注册失败！\n");
    }
    else if(res == 0)
    {
        PrintWran("注册成功！\n");
    }
    else if(res == 1)
    {
        PrintWran("重复注册！\n");
    }
    return res;
}

void initialUserOption(int *op)
{
    int option = 0;
	ClearScreen();
	PrintCenter("^^^^^^^^^^^^^^^ 欢迎使用通信录系统 ^^^^^^^^^^^^^^^\n\n");
    // 展示选项
    PrintCenter("1》登录        \n\n");
    PrintCenter("2》注册        \n\n");
    PrintCenter("3》退出        \n\n");
    PrintCenter("请输入1/2/3:             ");
    printf("\b\b\b\b\b\b\b\b\b\b\b\b\b");
    while(!(option == 1 || option == 2 || option == 3))
    {
        scanf("%d", &option);
    }
	*op = option;
}

//返回值 2 进入重启 1 退出 0 登录成功
//选择登录
int opLogin(PUserType pUser)
{
    while(1)
    {
        int res = loginPage(pUser);
        if(1 == res)// 用户不存在则
        {
            // 进入重启(页面)
            return 2;
        }
        else if(2 == res)// 重复登录
        {
            // 进入退出页面exit（页面）
            return 1;
        }
        else if(3 == res)// 密码不正确
        {
            // 进入登录login(页面)
            continue;
        }
        else if(-1 == res) //程序异常
        {
            continue;
        }
        else //登录成功
        {
            return 0;
        }   
    } 
}

//选择注册
//返回值 2 进入登录
int opRegister(PUserType pUser)
{
    while(1)
    {
        int res = registerPage(pUser);
        if(1 == res)//用户存在则
        {
            return 2;
        }
        else if(2 == res)// 注册失败则
        {
            continue;
        }
        else if(-1 == res)//程序异常
        {
            continue;
        }
        else//注册成功则
        {
            return 2;
        }
    }
}
/*
    参数：
        pUser 用户信息空间地址
    功能：起始页面
    返回值：
        1  用户退出
        0  登录成功
*/
int initialPage(PUserType pUser)
{
    int op = 0, res = 0;

    while(1)
    {
        // 检测用户输入
        initialUserOption(&op);
        
        //选择操作
        if(1 == op)//登录
        {
            res = opLogin(pUser);            
        }
        else if(2 == op)//注册
        {
            res = opRegister(pUser);
        }
        else//退出
        {
            // 进入退出页面exit（页面）
            res = 1;
        }
        if(1 == res || 0 == res)//1 退出 0 登录成功
        {
            return res;
        }
    }
}

//退出页面
void exitPage(PUserType *pUser, PSeqListType* pContactList)
{
    //样式还原
    printf("\33[0m");

    //用户登出
    RequestLogout(*pUser);

    //资源释放
    if(pUser != NULL && *pUser != NULL)
    {
        UserFree(pUser);
    }
    if(pContactList != NULL && *pContactList != NULL)
    {
        ContactFree(pContactList);
    }
    //3秒后退出
    ShowExit(3);
}

// -1 程序异常
// 1  退出成功
// 退出帐号
int opLogout(PUserType pUser)
{
    int res = RequestLogout(pUser);
    
    if(res == 1)// 登出成功则
    {
        // 提示登出成功
        PrintWran("登出成功!\n");
    }
    return res;
}


// -1 程序异常
// 3  取消注销
// 1  注销成功
// 退出帐号
int opDestroy(PUserType pUser)
{
    int res = 0;
    int option = 0;
    printf("是否注销？(否0/是1)\n");
    while(1)
    {
        scanf("%d", &option);
        if(option == 0)//取消注销
        {
            return 3;
        }
        if(option == 1)
        {
            break;
        }
    }
    
    
    res = RequestDestroy(pUser);
    if(res == -1)// 注消失败则
    {
        PrintWran("注消失败!\n");
        return -1;
    }
    else // 注消成功则
    {
        PrintWran("注消成功!\n");
         // 2》设置样式
        Style style = {0, 0, 0};
        SetColor(0, 0, 0);

        // 3》保存样式
        SaveStyle(pUser, style);
        return 1;
    }
}

void accountUserOption(int *op)
{
    int option = 0;
	ClearScreen();
	PrintCenter("^^^^^^^^^^^^^^^ 帐号管理页面(account) ^^^^^^^^^^^^^^^\n\n");
    // 展示选项
    PrintCenter("1》登出账号        \n\n");
    PrintCenter("2》注销账号        \n\n");
    PrintCenter("3》返回(home)页面  \n\n");
    PrintCenter("请输入1/2/3 :             ");
    printf("\b\b\b\b\b\b\b\b\b\b\b\b\b");
    while(!(option == 1 || option == 2 || option == 3))
    {
        scanf("%d", &option);
    }
	*op = option;
}

/*
    功能：帐号管理页面
    返回值:
    `   -1  程序异常
        1   返回重启
        3   返回home
*/
int accountPage(PUserType pUser)
{
    int op = 0, res = 0;

    while(1)
    {
        // 检测用户输入
        accountUserOption(&op);
        
        //选择操作
        if(1 == op)//登出
        {
            // -1 程序异常
            // 1  返回重启
            res = opLogout(pUser);            
        }
        else if(2 == op)//注销账号
        {
            // -1 程序异常
            // 1  返回重启
            res = opDestroy(pUser);
        }
        else//返回home
        {
            res =  3;
        }
        if(-1 == res || 1 == res || 3 == res)//-1程序异常  1返回重启 3返回home
        {
            return res;
        }
    }
}

/*
    功能：1)添加联系人
    返回值：
        -1 程序异常
        0  添加成功
        1 输入错误
*/
int opAddContact(PUserType pUser, PSeqListType pContactList)
{
    ElementType data = {};
    int res = 0;
    bool isValid = 0;
    while(1)
    {
        // 1》联系人信息录入
        ClearScreen();
        ChangeCenter(5);
        PrintCenter("请输入联系人姓名:");
        scanf("%s", data.contactInfo.name);
        PrintCenter("请输入联系人性别:");
        scanf("%s", data.contactInfo.gender);
        PrintCenter("请输入联系人年龄:");
        scanf("%d", &data.contactInfo.age);
        PrintCenter("请输入联系人电话:");
        scanf("%ld", &data.contactInfo.contactId);
        PrintCenter("请输入联系人住址:");
        scanf("%s", data.contactInfo.addres);


        isValid = isValidPhone(data.contactInfo.contactId) && isValidAge(data.contactInfo.age);
        
        if(!isValid)
        {    
            // 提示输入参数错误
            PrintWran("输入手机号/年龄不正确！\n");
            continue;
        }
        int post = IsContactExistByPhone(pContactList, data.contactInfo.contactId);
        if(post != -1) // 联系人存在则
        {
            // 提示输入参数错误
            PrintWran("联系人存在！\n");
            return 1;
        }
        else// 联系人不存在则
        {
            data.contactInfo.userId = pUser->userId;
            break;
        }
    }
    return InsertIntoContacts(pUser, pContactList, &data);
    // ElementType data;
	// int res = -1;
	// for(int i = 0; i < 5000; i++)
	// {
	// 	data.contactInfo = (ContactType){1000, 13554003465, "张伟", "男", 22,"黄石市青山区长江路1234号"};
	// 	data.contactInfo.userId = pUser->userId;
    //     InsertIntoContacts(pUser, pContactList, &data);//请求添加
	// }
    // return 0;
} 

/*
    功能：2)显示联系人
*/
void opDisplayContact(PSeqListType pContactList)
{
    // 1》进行显示
    // 显示通信录表
    if(pContactList->last == -1)
    {
        PrintWran("没有联系人\n");
    }
    else
    {
        ShowSeqlist(pContactList, 1);
        PrintCenter("输入任意键结束查看\n");
        getchar();
        getchar();
    }
}

/*
    功能：3)删除联系人
    参数：
        -1 程序异常
        0  删除成功
        1 返回
*/
int opDeleteContact(PUserType pUser, PSeqListType pContactList)
{
    if(pContactList->last == -1)
    {
        PrintWran("没有联系人\n");
        return 1;
    }
    else
    {
        bool isValid = 0;
        long phone = 0;
        int post = -1;

        while(1)
        {
            // 1》联系人信息录入
            ClearScreen();
            PrintCenter("输入删除联系人电话:");
            scanf("%ld", &phone);

            isValid = isValidPhone(phone);
            
            if(!isValid)
            {    
                // 提示输入参数错误
                PrintWran("输入手机号不正确！\n");
                // 校验失败则重新输入
                continue;
            }

            post = IsContactExistByPhone(pContactList, phone);
            if(post == -1) // 联系人不存在则
            {
                // 提示输入参数错误
                PrintWran("联系人不存在！\n");
                return 1;
            }
            else
            {
                break;
            }
        }
        return DeleteContacts(pContactList, &pContactList->data[post].contactInfo); 
    }
} 

/*
    功能：4)查找联系人
*/
void opSelectContact(PSeqListType pContactList)
{
    if(pContactList->last == -1)
    {
        PrintWran("没有联系人\n");
        return ;
    }
    else
    {
        // 1》查询联系人录入
        bool isValid = 0;
        char name[30] = "";
        int post = -1;

        while(1)
        {
            // 1)输入查询联系人姓名
            ClearScreen();
            ChangeCenter(1);
            PrintCenter("输入查询联系人姓名:");
            scanf("%s", name);

            // 2)检验姓名是否合法
            isValid = isValidName(name);
            
            if(!isValid)
            {    
                // 提示输入参数错误
                PrintWran("姓名不合规！\n");
                // 校验失败则重新输入
                continue;
            }
            else
            {
                break;
            }
        }

        //1）根据姓名在通信录中查找联系人
        ShowContactByName(pContactList, name);
        PrintCenter("输入任意键结束查看\n");
        getchar();
        getchar();
    }
}

/*
    功能：5)修改联系人
    参数：
        -1 程序异常
        0  修改成功
        1 联系人不存在
*/
int opModifyContact(PUserType pUser, PSeqListType pContactList)
{
    if(pContactList->last == -1)
    {
        PrintWran("没有联系人\n");
        return 1;
    }
    else
    {
        bool isValid = 0;
        long contactId = 0;
        ElementType data = {};
        int res = 0;

        while(1)
        {
            // 1》联系人信息录入
            ClearScreen();
            printf("输入修改联系人电话:");
            scanf("%ld", &contactId);

            isValid = isValidPhone(contactId);
            
            if(!isValid)
            {    
                // 提示输入参数错误
                PrintWran("输入手机号不正确！\n");
                // 校验失败则重新输入
                continue;
            }

            int post = IsContactExistByPhone(pContactList, contactId);
            if(post == -1) // 联系人不存在则
            {
                // 提示输入参数错误
                PrintWran("联系人不存在！\n");
                return 1;
            }
            else// 联系人存在则
            {
                data.contactInfo.contactId = pContactList->data[post].contactInfo.contactId;
                data.contactInfo.userId = pUser->userId;
                data.contactInfo.contactId = contactId;
                break;
            }
        }

        isValid = 0;
        while(1)
        {
            // 1》联系人信息录入
            ClearScreen();
            ChangeCenter(5);
            PrintCenter("输入联系人姓名:");
            scanf("%s", data.contactInfo.name);
            PrintCenter("输入联系人性别:");
            scanf("%s", data.contactInfo.gender);
            PrintCenter("输入联系人年龄:");
            scanf("%d", &data.contactInfo.age);
            PrintCenter("输入联系人住址:");
            scanf("%s", data.contactInfo.addres);

            isValid = isValidAge(data.contactInfo.age);
            
            if(!isValid)
            {    
                // 提示输入参数错误
                PrintWran("输入年龄不正确！\n");
                continue;
            }
            else
            {
                break;
            }
        }
        return ModifyContacts(pContactList, &data); 
    }
}  

/*
    功能：6)清空联系人
    参数：
        -1 程序异常
        0  清空成功
        1 返回
*/
int opClearContact(PUserType pUser, PSeqListType pContactList)
{
    if(pContactList->last == -1)
    {
        PrintWran("没有联系人\n");
        return 1;
    }
    else
    {
        return ClearContact(pUser, pContactList); 
    }
}  

void contactUserOption(int *op)
{
    int option = 0;
	ClearScreen();
	PrintCenter("^^^^^^^^^^^^^^^ 联系人管理界面(contact) ^^^^^^^^^^^^^^^\n\n");
    // 展示选项
    PrintCenter("1)添加联系人         \n\n");
    PrintCenter("2)显示联系人         \n\n");
    PrintCenter("3)删除联系人         \n\n");
    PrintCenter("4)查找联系人         \n\n");
    PrintCenter("5)修改联系人         \n\n");
    PrintCenter("6)清空联系人         \n\n");
    PrintCenter("7)返回(home)页面     \n\n");
    PrintCenter("请输入操作:             ");
    printf("\b\b\b\b\b\b\b\b\b\b\b\b\b");
    while(!(option == 1 || option == 2 || option == 3
    || option == 4 || option == 5 || option == 6 || option == 7))
    {
        scanf("%d", &option);
    }
	*op = option;
}

/*
    功能：联系人管理页面
    返回值:
    `   -1  程序异常
        3   返回home
*/
int contactPage(PUserType pUser, PSeqListType pContactList)
{
    int op = 0, res = 0;

    while(1)
    {
        // 检测用户输入
        contactUserOption(&op);
        //选择操作
        if(1 == op)// 1)添加联系人
        {
            // -1 程序异常
            // 0  添加成功
            //1 联系人存在
            res = opAddContact(pUser, pContactList);       
        }
        else if(2 == op)//2)显示联系人
        {
            opDisplayContact(pContactList);
        }
        else if(3 == op)// 3)删除联系人
        {
            // -1 程序异常
            // 0  删除成功
            //1 联系人不存在
            res = opDeleteContact(pUser, pContactList);            
        }
        else if(4 == op)// 4)查找联系人
        {
            opSelectContact(pContactList);            
        }
        else if(5 == op)// 5)修改联系人
        {
            // -1 程序异常
            // 0  修改成功
            //1 联系人不存在
            res = opModifyContact(pUser, pContactList);            
        }
        else if(6 == op)// 6)清空联系人
        {
            // -1 程序异常
            // 0  清空成功
            res = opClearContact(pUser, pContactList);
        }
        else//返回home
        {
            res =  3;
        }
        if(-1 == res || 3 == res)//-1程序异常  3返回home
        {
            return res;
        }
    }
}


// 功能：自定义风格样式
// -1 程序异常
// 0  添加成功
int opSelfStyle(PUserType pUser, PStyle pStyle)
{
    // /*				显示方式			前景色					背景色
    // 重置所有样式	"\033[0m"	黑色	"\033[30m"	黑色背景	"\033[40m"
    // 粗体			"\033[1m"	红色	"\033[31m"	红色背景	"\033[41m"
    // 下划线			"\033[3m"	绿色	"\033[32m"	绿色背景	"\033[42m"
    // 闪烁			"\033[4m"	黄色	"\033[33m"	黄色背景	"\033[43m"
    // 反显			"\033[5m" 	蓝色	"\033[34m"	蓝色背景	"\033[44m"
    // 隐藏			"\033[8m"	品红色	"\033[35m"	品红色背景	"\033[45m"
    //                 青色	"\033[36m"	青色背景	"\033[46m"
    //                 白色	"\033[37m"	白色背景	"\033[47m"
    // */	
	ClearScreen();
	PrintCenter("^^^^^^^^^^^^^^^ 界面风格设置界面(style) ^^^^^^^^^^^^^^^\n\n");
    // 1》样式展示
    PrintCenter("   显示方式            前景色                  背景色   \n\n");
    PrintCenter("   默认 0              红色 31                黄色背景 43\n\n");
    PrintCenter("   粗体 1              黑色 30                白色背景 47\n\n");
    PrintCenter("请输入显示方式 前景色 背景色:             ");
    printf("\b\b\b\b\b\b\b\b\b\b\b\b\b");
    scanf("%d%d%d", &pStyle->from, &pStyle->fGC, &pStyle->bGC);
	
    // 2》设置样式
    SetColor(pStyle->from, pStyle->fGC, pStyle->bGC);

    // 3》保存样式
    int res = SaveStyle(pUser, *pStyle);
    if(res == -1)// -1 程序异常
    {
        PrintWran("程序异常\n");
    }
    else// 0  设置成功
    {
        PrintWran("设置成功\n");
    }
    return 0;
}

void styleUserOption(int *op)
{
    int option = 0;
	ClearScreen();
	PrintCenter("^^^^^^^^^^^^^^^ 界面风格设置界面(style) ^^^^^^^^^^^^^^^\n\n");
    // 展示选项
    PrintCenter("1)风格自定义          \n\n");
    PrintCenter("2)返回(home)页面        \n\n");
    PrintCenter("请输入1/2:             ");
    printf("\b\b\b\b\b\b\b\b\b\b\b\b\b");
    while(!(option == 1 || option == 2))
    {
        scanf("%d", &option);
    }
	*op = option;
}

/*
    功能：界面风格设置界面
    返回值:
    `   -1  程序异常
        3   返回home
*/
int stylePage(PUserType pUser, PStyle pStyle)
{
    int op = 0, res = 0;

    while(1)
    {
        // 检测用户输入
        styleUserOption(&op);
        
        //选择操作
        if(1 == op)//1)风格自定义
        {
            // -1 程序异常
            // 0  设置成功
            res = opSelfStyle(pUser, pStyle);
        }
        else//返回home
        {
            res =  2;
        }
        if(-1 == res || 2== res)//-1程序异常  2返回home
        {
            return res;
        }
    }
}

/*
    参数：
        pUser 用户信息空间地址
        pContactList 通信录表空间地址
    功能：选择管理帐号
    返回值：
        0   返回home
        -1  程序异常
        1 返回重启
*/
int opAccount(PUserType pUser)
{
    while(1)
    {
        int res = accountPage(pUser);
        if(res == 3)//返回home 
        {
            return 0;
        }
        else
        {
            //-1)程序异常
            // 1 返回重启
            return res;
        }
    } 
}
 

/*
    参数：
        pUser 用户信息空间地址
        pContactList 通信录表空间地址
    功能：选择管理联系人
    返回值：
        0   返回home
        -1  程序异常
*/
int opContact(PUserType pUser, PSeqListType pContactList)
{   
    while(1)
    {
        int res = contactPage(pUser, pContactList);
        if(res == 3)//返回home 
        {
            return 0;
        }
        else
        {
            //-1)程序异常
            return res;
        }
    } 
}


/*
    参数：
        pUser 用户信息空间地址
    功能：选择样式
    返回值：
        0   返回home
        -1  程序异常
*/
int opStyle(PUserType pUser, PStyle pStyle)
{
    while(1)
    {
        int res = stylePage(pUser, pStyle);
        if(res == 3)//返回home 
        {
            return 0;
        }
        else
        {
            //-1)程序异常
            return res;
        }
    }
}
    
void HomeUserOption(int *op)
{
    int option = 0;
	ClearScreen();
	PrintCenter("^^^^^^^^^^^^^^^ 主页面(home) ^^^^^^^^^^^^^^^\n\n");
    // 展示选项
    PrintCenter("1》账号管理       \n\n");
    PrintCenter("2》联系人管理    \n\n");
    PrintCenter("3》界面风格设置 \n\n");
    PrintCenter("4》退出              \n\n");
    PrintCenter("请输入1/2/3/4:             ");
    printf("\b\b\b\b\b\b\b\b\b\b\b\b\b");
    while(!(option == 1 || option == 2 || option == 3 || option == 4))
    {
        scanf("%d", &option);
    }
	*op = option;
}

/*
    参数：
        pUser 用户信息空间地址
        pContactList 通信录表空间地址
    功能：主页面
    返回值：
        0   用户退出
        -1  程序异常
        1   返回重启
*/
int HomePage(PUserType pUser, PSeqListType pContactList)
{
    int op = 0, res = 0;
    Style style = {};

    //加载样式
    res = LoadStyle(pUser, &style);
    if(res == -1)
    {
        return -1;
    }
    SetColor(style.from, style.fGC, style.bGC);//设置样式

    while(1)
    {
        // 检测用户输入
        HomeUserOption(&op);
        
        //选择操作
        if(1 == op)//1账号管理
        {
            res = opAccount(pUser);
        }
        else if(2 == op)//2联系人管理
        {
            res = opContact(pUser, pContactList);
        }
        else if(3 == op)//3界面风格设置
        {
            res = opStyle(pUser, &style);
        }
        else//4退出
        {
            // 进入退出页面exit（页面）
            return 0;
        }

        if(res == -1 || res == 1)//程序异常 重启
        {
            return res;
        }
    }
}
  